package _struct

import "fmt"
import "study_demo/src/struct/employee1"

/** 结构体
结构体是用户定义的类型，表示若干个字段（Field）的集合。有时应该把数据整合在一起，而不是让这些数据没有联系。
这种情况下可以使用结构体。
例如，一个职员有firstName、lastName和age三个属性，而把这些属性组合在一个结构体employee中就很合理。

结构体声明语法：
type <命名> struct {
  ...
}


在方法中使用指针接收器 与 在函数中使用指针参数
	🔥 和值参数相类似，函数使用指针参数只接受指针，而使用指针接收器的方法可以使用值接收器和指针接收器。
*/

// 创建一个员工结构体
type Employee struct {
	// 姓名，手机号，地址，所属部门
	name, phone, address, deptName string
	age                            int
}

//

// 示例1
func case1() {

	// 使用案例
	emp1 := Employee{
		name:     "丽丽",
		phone:    "135260213652",
		address:  "北京市xxxx阳光别墅1栋2单元",
		deptName: "销售部",
		age:      22,
	}
	fmt.Println("emp1:", emp1)

	// 访问结构体字段
	fmt.Println("emp1.name:", emp1.name)
	fmt.Println("emp1.phone:", emp1.phone)
	fmt.Println("emp1.address:", emp1.address)
	fmt.Println("emp1.deptName:", emp1.deptName)
	fmt.Println("emp1.age:", emp1.age)

	// 修改结构体字段值
	emp1.age = 99
	fmt.Println("emp1:", emp1)

	// 创建匿名结构体
	emp2 := struct {
		userName, passWord string
		age                int
	}{
		userName: "admin",
		passWord: "123456",
		age:      22,
	}
	fmt.Println("emp2:", emp2)

	// 结构体
	var emp3 Employee
	fmt.Println("emp3:", emp3)

	// 结构体判断空有： 零值， 指针是nil， 反射等
	if emp3 == (Employee{}) {
		fmt.Println("emp3 是零值")
	}

	// 创建零值结构体
	var emp4 Employee
	emp4.name = "zhangSan"
	emp4.phone = "135260213652"
	fmt.Println("emp4:", emp4)

	// 指针结构体
	emp5 := &Employee{"zhangSan", "13623021361", "北京...", "销售", 99}
	fmt.Println("emp5:", emp5)
	fmt.Println("emp5.age:", (*emp5).age) // 指针解引用
	fmt.Println("emp5.age:", emp5.age)    // 结构体可使用这.的方式直接代替解引用

	// 判断结构相等
	emp6 := Employee{"wangwu", "13802136230", "上海", "销售", 0}
	emp7 := Employee{"wangwu", "13802136230", "上海", "销售", 0}
	if emp6 == emp7 {
		fmt.Println("emp6 == emp7")
	} else {
		fmt.Println("emp6 != emp7")
	}

}

func Test() {

	// 示例1
	case1()

	// 使用结构体
	dept1 := Dept{1, "销售部", false}
	dept1.toString()

	dept1.setName("迎宾部")
	dept1.toString()

	dept1.setDelFlag(true)
	dept1.toString()

	// 使用结构体2
	rectangle := Rectangle{23, 5}
	area(rectangle)
	rectangle.area()

	rr2 := &rectangle
	rr2.area() //通过指针调用值接收器

	// 示例3
	ee1 := employee1.Employee{FirstName: "Sam", LastName: "Adolf"}
	ee1.Tostring()

	// 示例4 🔥使用 new 来构建外部不可访问的结构体
	ee4 := employee1.NewEmp("Tom", 18)
	ee4.ToString()
}
